package util;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;

/**
 * UserRank: tum0r
 * Package Name: util
 * Time: 2019-01-30 Wednesday 13:27:19
 */
public class Excel {

    public static final String XLS = "xls";
    public static final String XLSX = "xls";

    private Sheet sheet;
    private Workbook workbook;

    private void getWorkbook(String path) throws IOException {
        getWorkbook(new File(path));
    }

    private void getWorkbook(File file) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(file);
        String fileName = file.getName().toLowerCase();
        if (fileName.endsWith(XLS)) {
            workbook = new HSSFWorkbook(fileInputStream);
        } else if (fileName.endsWith(XLSX)) {
            workbook = new XSSFWorkbook(fileInputStream);
        } else {
            throw new IOException("The excel file type error");
        }
    }

    public Excel() {
    }

    public boolean check(String path, String[] args) {
        return check(new File(path), args);
    }

    public boolean check(File file, String[] args) {
        return false;
    }

    public LinkedList<LinkedHashMap<String, String>> read(String path, String sheetName) throws IOException {
        return read(new File(path), sheetName);
    }

    public LinkedList<LinkedHashMap<String, String>> read(File file, String sheetName) throws IOException {
        getWorkbook(file);
        sheet = workbook.getSheet(sheetName);
        workbook.close();
        return getResult();
    }

    public LinkedList<LinkedHashMap<String, String>> read(String path, int sheetIndex) throws IOException {
        return read(new File(path), sheetIndex);
    }

    public LinkedList<LinkedHashMap<String, String>> read(File file, int sheetIndex) throws IOException {
        getWorkbook(file);
        sheet = workbook.getSheetAt(sheetIndex);
        workbook.close();
        return getResult();
    }

    private LinkedList<LinkedHashMap<String, String>> getResult() {
        if (sheet != null) {
            LinkedList<LinkedHashMap<String, String>> result = new LinkedList<LinkedHashMap<String, String>>();
            LinkedHashMap<String, String> item;
            int rowCount = sheet.getLastRowNum() + 1;
            Row line;
            Cell cell;
            Row columnName = sheet.getRow(0);
            Cell cellName;
            int columnCount = columnName.getLastCellNum() + 1;
            for (int row = 1; row < rowCount; row++) {
                item = new LinkedHashMap<String, String>();
                line = sheet.getRow(row);
                for (int column = 0; column < columnCount; column++) {
                    cell = line.getCell(column);
                    cellName = columnName.getCell(column);
                    cellName.setCellType(CellType.STRING);
                    if (cell != null) {
                        cell.setCellType(CellType.STRING);
                        item.put(cellName.getStringCellValue(), cell.getStringCellValue());
                    } else {
                        item.put(cellName.getStringCellValue(), "");
                    }
                }
                result.add(item);
            }
            return result;
        }
        return null;
    }

    public boolean write(String path, String sheetName, String[][] data) throws IOException {
        return write(new File(path), sheetName, data);
    }

    public boolean write(String path, String[][] data) throws IOException {
        return write(new File(path), "Sheet1", data);
    }

    public boolean write(File file, String[][] data) throws IOException {
        return write(file, "Sheet1", data);
    }

    public boolean write(File file, String sheetName, String[][] data) throws IOException {
        getWorkbook(file);
        sheet = workbook.createSheet(sheetName);
        if (data != null) {
            Row row;
            Cell cell;
            for (int rowCount = 0; rowCount < data.length; rowCount++) {
                row = sheet.createRow(rowCount);
                if (data[rowCount] != null) {
                    for (int columnCount = 0; columnCount < data[rowCount].length; columnCount++) {
                        cell = row.createCell(columnCount, CellType.STRING);
                        cell.setCellValue(data[rowCount][columnCount]);
                    }
                }
            }
        }
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        workbook.write(fileOutputStream);
        workbook.close();
        fileOutputStream.close();
        return true;
    }
}
